import React, { useState, useEffect, useRef } from "react";

interface Props {
  listStyle?: React.CSSProperties; // 可视图容器样式
  elementStyle?: React.CSSProperties; // 可视图元素样式
  children: React.ReactNode; // 可视图元素
  option?: IntersectionObserverInit; // 观察者配置对象
  getData: () => any; // 获取数据函数
  hasMoreData: boolean; // 是否还有更多数据
}

const VirtualList: React.FC<Props> = function ({
  listStyle,
  elementStyle,
  children,
  option,
  getData, // 获取数据函数
  hasMoreData, // 是否还有更多数据
}) {
  // 加载状态
  const [loading, setLoading] = useState(false);

  // 观察者对象实例
  const observerRef = useRef(null);

  useEffect(() => {
    // 创建观察者配置对象
    const IntersectionObserverInitOption = {
      root: null,
      rootMargin: "0px",
      threshold: 1.0,
      ...option, // 覆盖掉默认配置
    };

    // 创建回调函数
    const callback = (entries: IntersectionObserverEntry[]) => {
      // 遍历观察者实例的交叉区间
      entries.forEach(async (entry) => {
        // 如果交叉区间的目标元素是最后一个可见元素，并且没有正在加载数据，并且还有更多数据可加载，则加载更多数据
        if (entry.isIntersecting && !loading && hasMoreData) {
          setLoading(true); // 设置加载状态
          try {
            getData(); // 等待数据获取完成
          } catch (error) {
            console.error("Error fetching data:", error);
          } finally {
            setLoading(false); // 数据获取完成后设置加载状态为 false
          }
        }
      });
    };

    // 创建观察者实例
    const observer = new IntersectionObserver(
      callback,
      IntersectionObserverInitOption
    );

    // 判断元素是否创建
    if (observerRef.current) {
      // 观察目标元素
      observer.observe(observerRef.current);
    }

    // 组件卸载或者是依赖发生变化的时候，取消观察者实例
    return () => {
      observer.disconnect();
    };
  }, [getData, loading, setLoading, hasMoreData, option]);

  return (
    <div style={{ ...listStyle }}>
      {children}
      {/* 可视图元素 */}
      <div style={{ ...elementStyle }} ref={observerRef}>
        {hasMoreData ? "加载更多" : "没有更多数据"}
      </div>
    </div>
  );
};

export default VirtualList;
